package com.wongoing.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.web.multipart.MultipartFile;

import com.wongoing.util.DateConvert;
import com.wongoing.util.DateStyle;
import com.wongoing.util.FileUtil;
import com.wongoing.util.LogService;
import com.wongoing.util.ResourceUtil;
import com.wongoing.sys.viewmodel.JsonResult;
/**
 * 类功能说明 TODO:文件操作类
 * 类修改者	修改日期
 * 修改说明
* @author yuany yuany@mesnac.com
* @date 2016-5-20 17:21:14
 * @version V1.0
 */
public class FileUtil {

	private static final Logger logger = Logger.getLogger(FileUtil.class);

	private static final int BUFFER = 1024;
	
	/**
	 * 功 能: 拷贝文件(只能拷贝文件)
	 * 
	 * @param strSourceFileName
	 *            指定的文件全路径名
	 * @param strDestDir
	 *            拷贝到指定的文件夹
	 * @return 如果成功true;否则false
	 */
	public boolean copyTo(String strSourceFileName, String strDestDir) {
		File fileSource = new File(strSourceFileName);
		File fileDest = new File(strDestDir);

		// 如果源文件不存或源文件是文件夹
		if (!fileSource.exists() || !fileSource.isFile()) {
			logger.debug("源文件[" + strSourceFileName + "],不存在或是文件夹!");
			return false;
		}

		// 如果目标文件夹不存在
		if (!fileDest.isDirectory() || !fileDest.exists()) {
			if (!fileDest.mkdirs()) {
				logger.debug("目录文件夹不存，在创建目标文件夹时失败!");
				return false;
			}
		}

		try {
			String strAbsFilename = strDestDir + File.separator + fileSource.getName();

			FileInputStream fileInput = new FileInputStream(strSourceFileName);
			FileOutputStream fileOutput = new FileOutputStream(strAbsFilename);

			logger.debug("开始拷贝文件:");

			int count = -1;

			long nWriteSize = 0;
			long nFileSize = fileSource.length();

			byte[] data = new byte[BUFFER];

			while (-1 != (count = fileInput.read(data, 0, BUFFER))) {

				fileOutput.write(data, 0, count);

				nWriteSize += count;

				long size = (nWriteSize * 100) / nFileSize;
				long t = nWriteSize;

				String msg = null;

				if (size <= 100 && size >= 0) {
					msg = "\r拷贝文件进度:   " + size + "%   \t" + "\t   已拷贝:   " + t;
					logger.debug(msg);
				} else if (size > 100) {
					msg = "\r拷贝文件进度:   " + 100 + "%   \t" + "\t   已拷贝:   " + t;
					logger.debug(msg);
				}

			}

			fileInput.close();
			fileOutput.close();

			logger.debug("拷贝文件成功!");
			return true;

		} catch (Exception e) {
			logger.debug("异常信息：[");
			logger.error(e);
			logger.debug("]");
			return false;
		}
	}

	/**
	 * 功能说明：判断文件是否存在
	 * 修改说明：
	 * @author 吴兆强
	 * @date 2017年12月4日 下午4:55:35
	 * @param strFileName
	 * @return
	 */
	public static boolean isExists(String strFileName) {
		File fileDelete = new File(strFileName);
		return fileDelete.exists();
	}
	
	/**
	 * 删除指定的文件
	 * 
	 * @param strFileName
	 *            指定绝对路径的文件名
	 * @return 如果删除成功true否则false
	 */
	public static boolean delete(String strFileName) {
		File fileDelete = new File(strFileName);

		if (!fileDelete.exists() || !fileDelete.isFile()) {
			logger.debug("错误: " + strFileName + "不存在!");
			return false;
		}

		return fileDelete.delete();
	}

	/**
	 * 移动文件(只能移动文件)
	 * 
	 * @param strSourceFileName
	 *            是指定的文件全路径名
	 * @param strDestDir
	 *            移动到指定的文件夹中
	 * @return 如果成功true; 否则false
	 */
	public boolean moveFile(String strSourceFileName, String strDestDir) {
		if (copyTo(strSourceFileName, strDestDir))
			return this.delete(strSourceFileName);
		else
			return false;
	}

	/**
	 * 创建文件夹
	 * 
	 * @param strDir
	 *            要创建的文件夹名称
	 * @return 如果成功true;否则false
	 */
	public static boolean makedir(String strDir) {
		File fileNew = new File(strDir);

		if (!fileNew.exists()) {
			logger.info("文件夹不存在--创建文件夹");
			return fileNew.mkdirs();
		} else {
			logger.debug("文件夹存在");
			return true;
		}
	}

	/**
	 * 删除文件夹
	 * 
	 * @param strDir
	 *            要删除的文件夹名称
	 * @return 如果成功true;否则false
	 */
	public boolean rmdir(String strDir) {
		File rmDir = new File(strDir);
		if (rmDir.isDirectory() && rmDir.exists()) {
			String[] fileList = rmDir.list();

			for (int i = 0; i < fileList.length; i++) {
				String subFile = strDir + File.separator + fileList[i];
				File tmp = new File(subFile);
				if (tmp.isFile())
					tmp.delete();
				else if (tmp.isDirectory())
					rmdir(subFile);
				else {
					logger.debug("error!");
				}
			}
			rmDir.delete();
		} else
			return false;
		return true;
	}
	
	/**  
	* 函数功能说明
	* @author yuany yuany@mesnac.com
	* @date 2016-5-20 17:21:14
	* @Title: downFile 
	* @Description: TODO:下载文件
	* @param @param path
	* @param @param response
	* @param @param allPath
	* @param @throws FileNotFoundException
	* @param @throws IOException
	* @param @throws UnsupportedEncodingException    设定文件 
	* @return void    返回类型 
	* @throws 
	*/
	public static void downFile(String path, HttpServletResponse response, String allPath )
			throws FileNotFoundException, IOException, UnsupportedEncodingException
	{
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		OutputStream fos = null;
		InputStream fis = null;
		File uploadFile = new File(allPath);
		fis = new FileInputStream(uploadFile);
		bis = new BufferedInputStream(fis);
		fos = response.getOutputStream();
		bos = new BufferedOutputStream(fos);
		response.setHeader("Content-disposition", "attachment;filename="
				+ URLEncoder.encode(path, "utf-8"));
		int bytesRead = 0;
		byte[] buffer = new byte[8192];
		while ((bytesRead = bis.read(buffer, 0, 8192)) != -1) {
			bos.write(buffer, 0, bytesRead);
		}
		bos.flush();
		fis.close();
		bis.close();
		fos.close();
		bos.close();
	}
	/**  
	* 函数功能说明
	* @author yuany yuany@mesnac.com
	* @date 2016-5-20 17:21:14
	* @Title: saveFile 
	* @Description: TODO:保存文件
	* @param @param is
	* @param @param uploadedFileLocation
	* @param @throws FileNotFoundException
	* @param @throws IOException
	* @param @throws UnsupportedEncodingException    设定文件 
	* @return File 返回类型 
	* @throws 
	*/
	public static File saveFile(InputStream is, String uploadedFileLocation) {
		// TODO Auto-generated method stub
		File file = new File(uploadedFileLocation);
		OutputStream os = null;
		try {
			os = new FileOutputStream(file);
			byte buffer[] = new byte[4 * 1024];
			while ((is.read(buffer)) != -1) {
				os.write(buffer);
			}
			os.flush();
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("保存文件失败：" + e.getMessage(), e);
		} finally {
			try {
				os.close();
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("文件关闭失败：" + e.getMessage(), e);
			}
		}
		System.out.println(uploadedFileLocation+"文件大小"+file.length());
		if (file.length()<5) {
			file.delete();
			return null;
		}
		return file;
	}
	
	 public static String processFileName(String fileNameInput) {
	 String fileNameOutput = null;
	 fileNameOutput = fileNameInput.substring(
			 fileNameInput.lastIndexOf("\\") + 1, fileNameInput.length());
	 return fileNameOutput;
	 }
	 /**
		 * 功能说明：上传图片方法
		 * 修改说明：
		 * @author 吴兆强
		 * @date 2017年10月26日 下午8:35:54
		 * @param file
		 * @return
		 */
		public static Map<String,Object> uploadFile(String oldPath,String dir,MultipartFile file) {
			Map<String,Object> jsonResult = new HashMap<String, Object>();
			String msg = "";
			try {
				String fileName = file.getOriginalFilename();
				long fileSize = file.getSize();
				String exts = fileName.substring(fileName.lastIndexOf(".") + 1);
				if (fileSize > ResourceUtil.getUploadFileMaxSize()) {
					msg = "上传文件应小于" + (ResourceUtil.getUploadFileMaxSize()/(1024*1024)) + "MB!";
					jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
					LogService.getInstance().info("『功能：存储文件』失败 ,msg:" + msg);
					return jsonResult;
				}
				if (exts.indexOf(ResourceUtil.getUploadFileExts()) != -1) {
					msg = "上传格式应属于：" + ResourceUtil.getUploadFileExts();
					jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
					LogService.getInstance().info("『功能：存储文件』 ,msg:" + msg);
					return jsonResult;
				}
				
				//文件命名规则：
				fileName = dir + "_" + DateConvert.formatDateToString(new Date(), DateStyle.YYYYMMDDHHMMSS)+"."+exts;
//				ShiroUser shiroUser = SubjectUtil.getCurrentUser();
//				Integer userId = shiroUser.getUserId();
//				String loginType = shiroUser.getUserType();
//				fileName = dir +"_"+loginType+userId+imgName+"."+exts;
				String path = dir + File.separator + fileName;
				oldPath = (oldPath==null|| oldPath=="")?"upload\\\\tmp\\\\tmp_20171205085200.jpg":oldPath;
				oldPath =  ResourceUtil.getUploadImageProjectRoot() + oldPath;
				// 存储路径
				String dirPath = ResourceUtil.getUploadFileAbsoluteRoot() + dir;
				String filePath = ResourceUtil.getUploadFileAbsoluteRoot() + path;
				LogService.getInstance().debug(filePath);
				//删除原文件
				//防止误传地址误删信息
				if(oldPath.contains("upload")) {
					if (FileUtil.isExists(oldPath)) {
						FileUtil.delete(oldPath);
					}
				}
				//创建新的文件
				boolean resultDir = FileUtil.makedir(dirPath);
				if (resultDir == true) {
					File targetFile = new File(filePath);  
					file.transferTo(targetFile);
					jsonResult = JsonResult.jsonWsReturn(0, ResourceUtil.getUploadFileRelativeRoot()+path ,true);
					LogService.getInstance().info("『功能：储存文件』: ,fileName:"
							+ fileName + " ,msg:" + msg);
				} else {
					msg = "建立文件夹" + dir + "失败!";
					jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
					LogService.getInstance().error("建立文件夹" + dir + "失败，完整路径为：dirPath");
				}
			} catch (Exception e) {
				msg = "上传文件失败!";
				jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
				LogService.getInstance().error("上传文件失败",e);
			}
			return jsonResult;
		}
		/**
		 * 功能说明：上传视频方法（重载）
		 * 修改说明： 同时上传多张视频时，需要标识不同文件，以防覆盖
		 * @author 吴兆强
		 * @date 2017年10月26日 下午8:35:54
		 * @param file
		 * @return
		 */
		public static Map<String,Object> uploadVideo(String oldPath,String dir,MultipartFile file,Integer userId,String num) {
			Map<String,Object> jsonResult = new HashMap<String, Object>();
			String msg = "";
			try {
				String fileName = file.getOriginalFilename();
				long fileSize = file.getSize();
				String exts = fileName.substring(fileName.lastIndexOf(".") + 1);
				if (fileSize > ResourceUtil.getUploadFileMaxSize()) {
					msg = "上传视频应小于50MB!";
					jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
					return jsonResult;
				}
				if (exts.indexOf(ResourceUtil.getUploadFileExts()) != -1) {
					msg = "上传格式应属于：" + ResourceUtil.getUploadImageExts();
					jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
					return jsonResult;
				}
				//视频命名规则：
				fileName = dir+ userId+num+ "_" + DateConvert.formatDateToString(new Date(), DateStyle.YYYYMMDDHHMMSS)+"."+exts;
				String path = dir + File.separator + fileName ;
				oldPath = (oldPath==null|| oldPath=="")?"upload\\tmp\\tmp_20171205085200.mp4":oldPath;
				oldPath =  ResourceUtil.getUploadImageProjectRoot() + oldPath;
				//删除原文件
				//防止误传地址误删信息
				if(oldPath.contains("question")) {
					if (FileUtil.isExists(oldPath)) {
						FileUtil.delete(oldPath);
					}
				}
				// 存储路径
				String dirPath = ResourceUtil.getUploadFileAbsoluteRoot() + dir;
				String filePath = ResourceUtil.getUploadFileAbsoluteRoot() + path;
				boolean resultDir = FileUtil.makedir(dirPath);
				if (resultDir == true) {
					File targetFile = new File(filePath);  
					file.transferTo(targetFile);
					jsonResult = JsonResult.jsonWsReturn(0, ResourceUtil.getUploadFileRelativeRoot()+path ,true);
				} else {
					msg = "建立文件夹" + dir + "失败!";
					jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
				}
			} catch (Exception e) {
				msg = "上传视频失败!";
				jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
			}
			return jsonResult;
		}
}
